/*
题目: 找出克隆二叉树中的相同节点
给你两棵二叉树，原始树 original 和克隆树 cloned，以及一个位于原始树 original 中的目标节点 target。

其中，克隆树 cloned 是原始树 original 的一个 副本 。

请找出在树 cloned 中，与 target 相同 的节点，并返回对该节点的引用（在 C/C++ 等有指针的语言中返回 节点指针，其他语言返回节点本身）。



注意：你 不能 对两棵二叉树，以及 target 节点进行更改。只能 返回对克隆树 cloned 中已有的节点的引用。

https://leetcode.cn/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree
 */
public class GetTargetCopy {
    public final TreeNode getTargetCopy(final TreeNode ori, final TreeNode cloned, final TreeNode target) {
        // 层次遍历
        Queue<TreeNode> queue = new LinkedList<> ();
        queue.offer(ori);
        boolean isFound = false;

        int depth = -1, order = 0; // 深度 和 序号
        while(!queue.isEmpty() && ! isFound) {
            int size = queue.size();

            depth ++;
            order = 0; // 每一层 序号 从 0 开始
            while (size-- > 0) {
                TreeNode cur = queue.poll();
                if (cur == target) {
                    isFound = true;
                    break ;
                }

                if (cur.left != null)   queue.offer(cur.left);
                if (cur.right != null)  queue.offer(cur.right);
                order ++;
            }
        }

        queue.clear();
        queue.offer(cloned);

        int newDepth = -1, newOrder = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            newDepth ++;
            newOrder = 0;

            while (size-- > 0) {
                TreeNode cur = queue.poll();
                if (newDepth == depth && newOrder == order) {
                    return cur;
                }

                if (cur.left != null)   queue.offer(cur.left);
                if (cur.right != null)  queue.offer(cur.right);
                newOrder ++;
            }
        }
        return null;
    }
}
